package com.pgytesting.secondhandcar.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.pgytesting.secondhandcar.dao.BankCardInformationDao;
import com.pgytesting.secondhandcar.dao.McpUserInfoDao;
import com.pgytesting.secondhandcar.dao.McpUserOtherInformationDao;
import com.pgytesting.secondhandcar.model.BankCardInformation;
import com.pgytesting.secondhandcar.model.McpUserInfo;
import com.pgytesting.secondhandcar.model.McpUserOtherInformation;
import com.pgytesting.secondhandcar.service.McpUserInfoService;
import com.pgytesting.secondhandcar.util.FaceIDCard;
import com.pgytesting.secondhandcar.util.SessionUtil;
import com.pgytesting.secondhandcar.util.UtilMethod;
import com.pgytesting.secondhandcar.vo.Parameters;
import com.pgytesting.secondhandcar.vo.ResponseMessage;
import com.pgytesting.secondhandcar.vo.SMSCode;

import lombok.extern.slf4j.Slf4j;

/**
 * 用户信息(McpUserInfo)表服务实现类
 *
 * @author makejava
 * @since 2019-08-12 18:55:58
 */
@Slf4j
@Service("mcpUserInfoService")
public class McpUserInfoServiceImpl implements McpUserInfoService {
    @Resource
    private McpUserInfoDao mcpUserInfoDao;

    @Resource
    private McpUserOtherInformationDao otherInformationDao;

    @Resource
    private BankCardInformationDao bankCardInformationDao;

    /**
     * 通过ID查询单条数据
     *
     * @param userNumber 主键
     * @return 实例对象
     */
    @Override
    public McpUserInfo queryById(String userNumber) {
        return this.mcpUserInfoDao.queryById(userNumber);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<McpUserInfo> queryAllByLimit(int offset, int limit) {
        return this.mcpUserInfoDao.queryAllByLimit(offset, limit);
    }

    /**
     * 条件查询多条数据
     *
     * @return 对象列表
     */
    @Override
    public ResponseMessage queryAll() {
        // 利用当前登录用户查询用户信息，以及其他信息
        McpUserInfo mcpUserInfo = this.mcpUserInfoDao.queryById(SessionUtil.getSessionMcpUser().getUserNumber());
        McpUserOtherInformation information = this.otherInformationDao.queryById(mcpUserInfo.getUserNumber());
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("userNumber", information.getUserNumber());
        resultMap.put("userAvatar", information.getUserAvatar());
        resultMap.put("nickname", information.getUserNickname());
        resultMap.put("sex", information.getUserSex());
        resultMap.put("phoneNumber", mcpUserInfo.getPhoneNumber());
        resultMap.put("userBirthday", information.getUserBirthday());
        resultMap.put("userName", mcpUserInfo.getUserName());
//        resultMap.put("type", "1");
        resultMap.put("identificationNumber", mcpUserInfo.getIdentificationNumber());
        return ResponseMessage.successResponse(resultMap, "查询成功");
    }

    /**
     * 条件查询多条数据
     *
     * @return 对象列表
     */
    @Override
    public List<McpUserInfo> queryAll(McpUserInfo mcpUserInfo) {
        return mcpUserInfoDao.queryAll(mcpUserInfo);
    }

    /**
     * 新增数据
     *
     * @param mcpUserInfo 实例对象
     * @return 实例对象
     */
    @Override
    public ResponseMessage register(McpUserInfo mcpUserInfo) {
        // 进行短信验证码校验
        SMSCode smsCode = SessionUtil.getSessionSMSCode();
        if (smsCode == null) {
            return ResponseMessage.errorResponse("未查询到短信验证码或已被使用，请重新获取");
        } else if (smsCode.getCurrentTime() <= UtilMethod.unixLong()) {
            ResponseMessage.errorResponse("短信验证码过期");
        } else if (!mcpUserInfo.getSmsCode().equals(smsCode.getSmsCode())) {
            return ResponseMessage.errorResponse("短信验证码错误");
        } else if (!mcpUserInfo.getPhoneNumber().equals(smsCode.getPhoneNumber())) {
            return ResponseMessage.errorResponse("短信验证码与手机号不符");
        }
        // 验证通过移除短信验证码
        SessionUtil.removeSMSCode();
        if (mcpUserInfoDao.queryCount(mcpUserInfo) != null) {
            return ResponseMessage.errorResponse("手机号已被注册");
        }
        // 补充账号信息
        mcpUserInfo.setUserNumber(UtilMethod.getUniqueCode());
        mcpUserInfo.setPassword(UtilMethod.md5Encryption(mcpUserInfo.getPassword()));
        Integer affected = 0;
        try {
            affected = this.mcpUserInfoDao.insert(mcpUserInfo);
        } catch (DuplicateKeyException e) {
            return ResponseMessage.errorResponse("手机号已被注册");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            return ResponseMessage.errorResponse("注册用户异常");
        }
        // 进行用户其他信息添加
        McpUserOtherInformation otherInformation = new McpUserOtherInformation();
        otherInformation.setUserNumber(mcpUserInfo.getUserNumber());
        otherInformation.setUserPhoneNumber(mcpUserInfo.getPhoneNumber());
        try {
            affected = otherInformationDao.insert(otherInformation);
        } catch (Exception e) {
            log.error("用户其他信息插入失败，进行数据库回退");
            this.mcpUserInfoDao.deleteById(mcpUserInfo.getPhoneNumber());
            log.error(e.getLocalizedMessage());
            return ResponseMessage.errorResponse("注册用户异常");
        }
        if (affected < 1) {
            try {
                this.mcpUserInfoDao.deleteById(mcpUserInfo.getPhoneNumber());
                otherInformationDao.deleteById(otherInformation.getUserNumber());
            } catch (Exception e) {
                return ResponseMessage.errorResponse("注册用户异常，数据回退异常，请联系管理员");
            }
            return ResponseMessage.errorResponse("注册用户失败");
        }
        // 为前端补齐数据
        Map map = new HashMap();
        map.put("carDealerInvitationCode", "");
        return ResponseMessage.successResponse(map, "注册用户成功");
    }

    /**
     * 修改数据
     *
     * @param mcpUserInfo 实例对象
     * @return 实例对象
     */
    @Override
    public ResponseMessage update(McpUserInfo mcpUserInfo) {
        // 进行变量转移，防止利用后台修改其他数据
        McpUserInfo mcpUser = new McpUserInfo();
        mcpUser.setSmsCode(mcpUserInfo.getSmsCode());
        mcpUser.setPhoneNumber(mcpUserInfo.getPhoneNumber());
        // 进行短信验证码校验
        SMSCode smsCode = SessionUtil.getSessionSMSCode();
        if (smsCode == null) {
            return ResponseMessage.errorResponse("未查询到短信验证码或已被使用，请重新获取");
        } else if (smsCode.getCurrentTime() <= UtilMethod.unixLong()) {
            ResponseMessage.errorResponse("短信验证码过期");
        } else if (!mcpUser.getSmsCode().equals(smsCode.getSmsCode())) {
            return ResponseMessage.errorResponse("短信验证码错误");
        } else if (!mcpUser.getPhoneNumber().equals(smsCode.getPhoneNumber())) {
            return ResponseMessage.errorResponse("短信验证码与手机号不符");
        }
        // 验证通过移除短信验证码
        SessionUtil.removeSMSCode();
        // 通过session中存储的信息获取用户信息
        mcpUser.setUserNumber(SessionUtil.getSessionMcpUser().getUserNumber());
        Integer updateCount = 0;
        try {
            updateCount = mcpUserInfoDao.update(mcpUser);
        } catch (Exception e) {
            log.error("修改绑定手机号异常", e.getLocalizedMessage());
            return ResponseMessage.errorResponse("修改绑定手机号异常");
        }
        if (updateCount < 1) {
            return ResponseMessage.errorResponse("修改绑定手机号失败");
        }
        return ResponseMessage.successResponse("修改绑定手机号成功");
    }

    /**
     * 实名认证
     *
     * @param mcpUserInfo 实例对象
     * @return
     */
    @Override
    public ResponseMessage updateOtherInformation(McpUserInfo mcpUserInfo) {
        String identificationNumber = mcpUserInfo.getIdentificationNumber();
        // 调用旷视科技身份证识别系统进行信息提取
        ResponseMessage response = FaceIDCard.getFaceIDCard(mcpUserInfo.getIdCardFacade());
        if (!response.isSuccess()) {
            return response;
        }
        // 获取信息成功,进行数据转换
        JSONObject jsonObject = JSONObject.parseObject(String.valueOf(response.getData()));
        String userName = jsonObject.getString("name");
        String idCardNumber = jsonObject.getString("id_card_number");
        if (!idCardNumber.equals(identificationNumber) || !userName.equals(mcpUserInfo.getUserName())) {
            return ResponseMessage.errorResponse("身份证信息校验错误，绑定失败");
        }
        McpUserInfo user = new McpUserInfo();
        user.setUserName(userName);
        user.setIdCardFacade(mcpUserInfo.getIdCardFacade());
        user.setIdCardNegative(mcpUserInfo.getIdCardNegative());
        user.setIdentificationNumber(idCardNumber);
        user.setUserNumber(SessionUtil.getSessionMcpUser().getUserNumber());
        Integer affected = 0;
        try {
            affected = mcpUserInfoDao.update(user);
        } catch (Exception e) {
            log.error("更新身份证信息异常", e);
            return ResponseMessage.errorResponse("绑定身份证信息异常");
        }
        if (affected < 1) {
            return ResponseMessage.errorResponse("绑定身份证信息失败");
        }
        return ResponseMessage.successResponse("绑定身份证信息成功");
    }

    /**
     * 绑定银行卡
     *
     * @param mcpUserInfo 实例对象
     * @return
     */
    @Override
    public ResponseMessage bindingBankCard(McpUserInfo mcpUserInfo) {
        // 进行短信验证码校验
        SMSCode smsCode = SessionUtil.getSessionSMSCode();
        if (smsCode == null) {
            return ResponseMessage.errorResponse("未查询到短信验证码或已被使用，请重新获取");
        } else if (smsCode.getCurrentTime() <= UtilMethod.unixLong()) {
            ResponseMessage.errorResponse("短信验证码过期");
        } else if (!mcpUserInfo.getSmsCode().equals(smsCode.getSmsCode())) {
            return ResponseMessage.errorResponse("短信验证码错误");
        } else if (!mcpUserInfo.getPhoneNumber().equals(smsCode.getPhoneNumber())) {
            return ResponseMessage.errorResponse("短信验证码与手机号不符");
        }
        // 验证通过移除短信验证码
        SessionUtil.removeSMSCode();
        // 进行银行卡是否被绑定验证
        if (!ObjectUtils.isEmpty(bankCardInformationDao.queryById(mcpUserInfo.getBankCardNumber()))) {
            return ResponseMessage.errorResponse("银行卡已被绑定");
        }
        // 信息验证成功，进行银行卡绑定
        if (!UtilMethod.matchLuhn(mcpUserInfo.getBankCardNumber())) {
            return ResponseMessage.errorResponse("银行卡信息验证失败");
        }
        McpUserInfo user = new McpUserInfo();
        BankCardInformation bank = new BankCardInformation();
        McpUserInfo m = SessionUtil.getSessionMcpUser();
        HttpSession session = SessionUtil.getSession();
        String userNumber = SessionUtil.getSessionMcpUser().getUserNumber();
        String phoneNumber = SessionUtil.getSessionMcpUser().getPhoneNumber();
        bank.setUserNumber(userNumber);
        bank.setBankCardNumber(mcpUserInfo.getBankCardNumber());
        bank.setBankCardName(mcpUserInfo.getBankCardName());
        if (StringUtils.isEmpty(userNumber)) {
            return ResponseMessage.errorResponse("请重新登录");
        }
        McpUserInfo McpUserInf = mcpUserInfoDao.queryById(userNumber);
        if (!ObjectUtils.isEmpty(McpUserInf)) {
            if (!phoneNumber.equals(McpUserInf.getPhoneNumber())) {
                SessionUtil.getSession().removeAttribute("user");
                return ResponseMessage.errorResponse("登录非法，请重新登陆");
            }
        }
        // 验证是否初次绑卡
        if (StringUtils.isEmpty(McpUserInf.getBankCardNumber())) {
            // 初次绑定，进行ID生成
            user.setBankCardNumber(bank.getBankCardNumber());
            // 0是默认卡，设置当前绑定卡为默认卡
            bank.setWhetherTheDefaultCard(0);
        } else {
            bank.setUserNumber(userNumber);
            bank.setWhetherTheDefaultCard(-1);
        }

        bank.setCreatedBy(phoneNumber);
        user.setUserNumber(userNumber);
        user.setPhoneNumber(phoneNumber);
        user.setBankCardName(mcpUserInfo.getBankCardName());
        Integer count = 0;
        try {
            count = bankCardInformationDao.insert(bank);
        } catch (Exception e) {
            log.error("绑定银行卡异常", e);
            return ResponseMessage.errorResponse("绑定银行卡异常");
        }
        if (count < 1) {
            return ResponseMessage.errorResponse("绑定银行卡失败");
        }
        try {
            count = mcpUserInfoDao.update(user);
        } catch (Exception e) {
            log.error("绑定银行卡异常,进行数据回滚", e);
            bankCardInformationDao.deleteById(bank.getBankCardNumber());
            return ResponseMessage.errorResponse("绑定银行卡异常");
        }
        if (count < 1) {
            log.error("绑定银行卡错误,进行数据回滚");
            bankCardInformationDao.deleteById(bank.getBankCardNumber());
            return ResponseMessage.errorResponse("绑定银行卡失败");
        }
        return ResponseMessage.successResponse("绑定银行卡成功");
    }

    /**
     * 通过主键删除数据
     *
     * @param userNumber 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String userNumber) {
        return this.mcpUserInfoDao.deleteById(userNumber) > 0;
    }

    /**
     * 登录
     *
     * @return
     */
    @Override
    public ResponseMessage queryLogin(McpUserInfo mcpUserInfo) {
        // 对密码进行加密处理
        mcpUserInfo.setPassword(UtilMethod.md5Encryption(mcpUserInfo.getPassword()));
        try {
            McpUserInfo mcpUser = mcpUserInfoDao.queryLogin(mcpUserInfo);
            if (mcpUser == null) {
                return ResponseMessage.errorResponse("账号密码错误或者不存在");
            }

            mcpUser.setCarDealerInvitationCode("");
            SessionUtil.updateSession("login", Parameters.USER_TYPE_USER);
            SessionUtil.updateSession("user", mcpUser);
            return ResponseMessage.successResponse(mcpUser, "登陆成功");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            return ResponseMessage.errorResponse("登录信息获取异常");
        }
    }

    @Override
    public Map<String, Object> queryUserDetail(McpUserInfo mcpUserInfo) {
        return mcpUserInfoDao.queryUserDetail(mcpUserInfo);
    }
}